package com.googlecode.lightest.studio

import grails.util.DomainBuilder

class TestReaderServiceTests extends GroovyTestCase {
    def reader
    def builder

    @Override
    void setUp() {
        reader = new TestReaderService()
        builder = new DomainBuilder()
        builder.setClassNameResolver('com.googlecode.lightest.studio')
    }

    void testReadFile() {
        def tests = [
            [
                "@Test",
                builder.test (name: 'anyTest', className: 'SomeTest')
            ]
            , [
                "@Test(description = 'foo')",
                builder.test (name: 'anyTest', className: 'SomeTest', description: 'foo')
            ]
            , [
                "@Test(groups = [ 'bar', 'baz' ])",
                builder.test (name: 'anyTest', className: 'SomeTest') {
                    annotation (name: 'org.testng.annotations.Test', member: 'groups', values: [ 'bar', 'baz' ])
                }
            ]
            , [
                "@Test(description = 'foo', groups = [ 'bar', 'baz' ])",
                builder.test (name: 'anyTest', className: 'SomeTest', description: 'foo') {
                    annotation (name: 'org.testng.annotations.Test', member: 'groups', values: [ 'bar', 'baz'])
                }
            ]
            , [
                "@Test @Parameters([ 'qux' ])",
                builder.test (name: 'anyTest', className: 'SomeTest') {
                    annotation (name: 'org.testng.annotations.Parameters', values: [ 'qux' ])
                }
            ]
        ]

        for (test in tests) {
            def annotationText = test[0]
            def expectedResult = test[1]

            def testFile = createTestFile(annotationText)
            def classLoader = new GroovyClassLoader(this.class.classLoader.rootLoader)
            def results = reader.readFile(testFile, classLoader)

            assertEquals(annotationText, 1, results.size())
            assertEquivalent(annotationText, expectedResult, results.toArray()[0])
        }
    }

    private File createTestFile(String annotationText) {
        def testFile = File.createTempFile('Test', '.groovy')

        testFile.deleteOnExit()
        testFile.text =
            """
            import com.googlecode.lightest.core.LightestTestCase
            import org.testng.annotations.*

            class SomeTest extends LightestTestCase {
                ${annotationText}
                void anyTest() {}
            }
            """
        
        return testFile
    }

    private void assertEquivalent(String message, Test expectedTest,
        Test actualTest)
    {
        assertEquals(message, expectedTest, actualTest)

        def expectedAnnotations = expectedTest.annotations
        def actualAnnotations = actualTest.annotations

        assertEquals(message, expectedAnnotations?.size(), actualAnnotations?.size())

        for (expectedAnnotation in expectedAnnotations) {
            def actualAnnotation = actualAnnotations.find { it.equals(expectedAnnotation) }

            assertNotNull(message, actualAnnotation)

            def expectedValues = expectedAnnotation.values
            def actualValues = actualAnnotation.values

            assertEquals(message, expectedValues?.size(), actualValues?.size())

            for (expectedValue in expectedValues) {
                assertTrue(message, actualValues.contains(expectedValue))
            }
        }
    }
}
